using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using GuavaData;

namespace CORIDemo
//namespace GuavaLib
{
	/// <summary>
	/// Summary description for findtag.
	/// </summary>
	public class FindTags : System.Windows.Forms.Label
	{
		private FindTags tag_next;				
		private FindTags tag_base;

		private Control		_parentForm;		// our custom drawing control;

		private Graphics	_graph;
		private Pen			_pen;			
		private SolidBrush	_brush;
		private Rectangle	drawRect;

		private bool	dragOn;				// user is dragging a label
		private int		tagX, tagY;					// point on the label control for drag
		public int		fx, fy;						// point in pic space that gets labeled
		public int		type;						// type of drawing
		public Guid		guid;						// the finding ID key
		public short[]	DrawingPoints;			// x,y coordinates

		// *** events ***
		public delegate void EventFindClick(FindTags ftag, Guid fid);
		public event EventFindClick FindClick;
		public event EventHandler ADraw;
		public event EventHandler Delrow;

		private DataRow datarow;
		private ContextMenu amenu;
		private System.ComponentModel.Container components = null;

		private FindTags(FindTags basetag, DataRow dtrow)
		{
			tag_base = basetag;
			// this will create a reversed list
			tag_next = tag_base.tag_next;
			tag_base.tag_next = this;

			datarow = dtrow;
			fx   = (int)(short)	datarow["x"];
			fy   = (int)(short)	datarow["y"];
			Text = (string)		datarow["caption"];
			type = (int)(byte)	datarow["kind"];
			guid = (Guid)		datarow["fk"];

			if (type > 1)
				GetPointsFromData();

			drawRect = tag_base.drawRect;
			Left = (int)(short) datarow["txtLeft"] + drawRect.Left;
			Top  = (int)(short) datarow["txtTop"]  + drawRect.Top;
			
			amenu = new ContextMenu();
			amenu.MenuItems.Add("Delete", new EventHandler(Delete_Finding));

			MouseDown += new System.Windows.Forms.MouseEventHandler(InMouseDown);
			MouseMove += new System.Windows.Forms.MouseEventHandler(InMouseMove);
			MouseUp   += new System.Windows.Forms.MouseEventHandler(InMouseUp);
			Click     += new  System.EventHandler(FindTag_Click);
			DoubleClick += new System.EventHandler(FindTag_DoubleClick);

			BackColor = Color.Cornsilk;
			BorderStyle = BorderStyle.FixedSingle;
			AutoSize = true;
			Parent = tag_base._parentForm;
			dragOn = false;

			BringToFront();
			DrawConnect();
		}

		public FindTags(Control par, Graphics g, Pen p, SolidBrush b, Rectangle dRect) // : base()
		{
			_parentForm = par;
			_graph = g;
			_pen = p;
			_brush = b;
			drawRect = dRect;
			tag_base = this;
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if( components != null )
					components.Dispose();
			}
			base.Dispose( disposing );
		}

		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
		}
		#endregion


		#region FindTags Create - Init

		public FindTags AddTag(DataRow dtrow)
		{
			/// get a new tag and link it
			FindTags f = new FindTags(this, dtrow);
			return f;
		}

		public FindTags[] GetTags()
		{
			Debug.Assert(tag_base == this);
			int count = 0;
			FindTags f = tag_next;
			while (f != null)
			{
				count++;
				f = f.tag_next;
			}
			FindTags [] ftgs = new FindTags[count];
			f = tag_next;
			count = 0;
			while (f != null)
			{
				ftgs[count++] = f;
				f = f.tag_next;
			}
			return ftgs;
		}

		#endregion // FindTag Create - Init - get

		#region FindTag Mouse

		private void FindTag_Click(object sender, System.EventArgs e)
		{
            if (dragOn)  // clicked with the right button
				return;
			if (FindClick == null)
			{
				Debug.Assert(false, "FindTag Click Event IS NULL");
				return;
			}
			//FindClick(this, guid);
		}

		private void FindTag_DoubleClick(object sender, System.EventArgs e)
		{
            Guid found = guid;
            foreach (DataRow row in AppData.ds.Tables["proc_find"].Rows)
            {
                
                if ((short)row["x"] == this.fx && (short)row["y"] == this.fy)
                {
                    found = (Guid)row["id"];
                }
            }
            
			this.FindClick(this, found);
		}

		private void InMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			//if(AppData.Read_only)
			//	return;

			if (e.Button == MouseButtons.Left)
			{
				if(e.Clicks == 1)
				{
					tagX = e.X;
					tagY = e.Y;
					dragOn = true;
					this.BringToFront();
				}
				else if(e.Clicks == 2)
					dragOn = false;
			}
			else if(e.Button == MouseButtons.Right)
			{
				this.amenu.Show(this, new Point(e.X, e.Y));
			}
		}

		private void InMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (!dragOn)
				return;
			// mouse position change
			int dx = tagX - e.X;
			int dy = tagY - e.Y;
			// new label position
			int x = this.Left - dx;
			int y = this.Top - dy;
			// bounds adjust
			if (x > (drawRect.Left + drawRect.Width))
				x = drawRect.Left + drawRect.Width;
			if (x < (drawRect.Left - this.Width))
				x = drawRect.Left - this.Width;
			if (y > (drawRect.Top + drawRect.Height))
				y = drawRect.Top + drawRect.Height;
			if (y < (drawRect.Top - this.Height))
				y = drawRect.Top - this.Height;
			// save
			this.Left = x;
			this.Top = y;
			datarow["txtLeft"] = x - drawRect.Left;
			datarow["txtTop"]  = y - drawRect.Top;
		}

		private void InMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if (dragOn)
			{
				tag_base._parentForm.Invalidate(true);
				dragOn = false;
				if (ADraw != null)
					ADraw(this, new System.EventArgs());
			}
		}
		#endregion // FindTag Mouse

		#region FindTag Drawing

		public void Draw()
		{
			FindTags a = tag_next;
			while (a != null)
			{
				a.DrawConnect();
				a = a.tag_next;
			}
		}

		public void DrawConnect()
		{
			int x1 = fx;
			int y1 = fy;
			int x2 = this.Left - drawRect.Left;
			int y2 = this.Top - drawRect.Top;
			// x2 y2 is the upper left corner of the label in pic coordinates
			if (x2 < x1)	// if label left is left of point
			{
				if ((x2 + this.Width) > x1)  // if the point x is in the label width
					x2 = x1;
				else
					x2 += this.Width;		  // move to right corner
			}
			//-------------------
			if (y2 > y1)	// do nothing
				y2 = y2;
			else if (y2 + this.Height > y1)	// if the point is below the top of the label
				y2 = y1;
			else
				y2 += this.Height;
			tag_base._graph.DrawLine(tag_base._pen, x1, y1, x2, y2);
			// now draw the dot at the end of the line
			tag_base._graph.FillEllipse(tag_base._brush, fx-4, fy-4, 8, 8);
		}
		#endregion // FindTag Drawing

		private short getStringInt(string s, ref int n)
		{
			short x = 0;
			int len = s.Length;
			while ((s[n] >= '0') && (s[n] <= '9'))
			{
				x *= 10;
				x += (short)(s[n] - '0');
				n++;
				if (n >= len)
					break;
			}
			return x;
		}


		private void GetPointsFromData()
		{
			string s = datarow["points"].ToString();
			Debug.Assert(s.Length > 4);
			int count, n, i, j;
			j = i = n = 0;
			count = getStringInt(s, ref n);
			DrawingPoints = new short[count*2];
			while (j < count)
			{
				Debug.Assert(s[n] == ',');
				n++;
				// TODO: check for errors
				DrawingPoints[i++] = getStringInt(s, ref n);
				Debug.Assert(s[n] == ' ');
				n++;
				// TODO: check for errors
				DrawingPoints[i++] = getStringInt(s, ref n);
				j++;
			}
		}

		/*
		public void render(Graphics g, int x, int y, int w, int h)
		{
			int x2 = this.Left - drawRect.Left + x;
			int y2 = this.Top - drawRect.Top + y;
			// draw the rectangle
			Pen p = new Pen(Color.Chocolate);
			Rectangle r = new Rectangle(x2, y2,  this.Width, this.Height);
			g.DrawRectangle(p, r);
			p.Dispose();
			// Draw the text
			SolidBrush brush = new SolidBrush(Color.DarkBlue);
			StringFormat drawFormat = new StringFormat();
			drawFormat.Alignment = StringAlignment.Center;
			g.DrawString(this.Text, this.Font, brush, r, drawFormat);
			brush.Dispose();
		}


		public void Render(Graphics g, int x, int y, int w, int h)
		{
			FindTags a = tag_next;
			while (a != null)
			{
				a.render(g, x, y, w, h);
				a = a.tag_next;
			}
		}
		*/

		private void Delete_Finding(object sender, System.EventArgs e)
		{
			//DialogResult res = MessageBox.Show(this,"Deleting this finding will remove all therapies and pathology data documented with the finding. \nDo you wish to continue?",
			//	 "Delete finding",MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
			//DeleteConfirm delCon = new DeleteConfirm();
			//delCon.ShowDialog();
			//if(res != DialogResult.OK)
			//	return;

			//if(!delCon.Delete)
			//	return;
			
			DeleteATag(this.guid);
			this.Visible = false;
			if(Delrow != null)
				Delrow(this, new System.EventArgs());

			//check delete the PathID's if the finding is deleted.
			//CorUI.Comps.CorForm cfm = new CorUI.Comps.CorForm();
			//cfm.checkDeletePathIDs(this.guid);
			
		}

		private void DeleteATag(Guid aguid)
		{
			FindTags prev, curr = tag_base;
			Guid dgid;
			prev = curr;
			int count = 0;
			while (curr != null)
			{
				dgid = curr.guid;
				if(dgid.Equals(aguid))
				{
					if(datarow != null)
					{
						if(datarow.RowState != DataRowState.Added)
							datarow["diff"] = (byte)3;
						else
							datarow.Delete();
					}
					if(count > 0)
					{
						prev.tag_next = curr.tag_next;
						curr.Visible = false;
						curr = curr.tag_next;
						continue;
					}
					else
					{
						tag_base = curr.tag_next;
						return;
					}
				}
				prev = curr;
				curr = curr.tag_next;
				count++;
			}
		}

	}
}
